package com.xinhe.web.service;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.xinhe.web.common.Result;
import com.xinhe.web.entity.Address;
import com.xinhe.web.entity.BankCard;
import com.xinhe.web.entity.QAddress;
import com.xinhe.web.entity.QBankCard;
import com.xinhe.web.reposity.AddressRepository;
import com.xinhe.web.reposity.BankCardRepository;
import com.xinhe.web.session.UserSessionManager;
import com.xinhe.web.util.Snowflake;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.inject.Provider;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Objects;

@Service
public class AddressService {
    @Autowired
    private AddressRepository addressRepository;
    @Autowired
    private UserSessionManager userSessionManager;
    @Autowired
    private BankCardRepository bankCardRepository;
    //查询工厂
    private JPAQueryFactory queryFactory;
    @Autowired
    private Provider<EntityManager> entityManager;
    @PostConstruct
    public void init() {
        queryFactory = new JPAQueryFactory(entityManager);
    }

    public QueryResults<Address> pageAddress(Long userId, int pageNum, int pageSize) {
        QAddress qAddress = QAddress.address;
        BooleanBuilder builder = new BooleanBuilder();
        if (!Objects.isNull(userId)){
            builder.and(qAddress.userId.eq(userId));
        }
        return queryFactory.select(
                        Projections.bean(
                                Address.class,
                                qAddress.name,
                                qAddress.isDefault,
                                qAddress.id,
                                qAddress.area,
                                qAddress.areaId,
                                qAddress.cityId,
                                qAddress.city,
                                qAddress.province,
                                qAddress.detail,
                                qAddress.provinceId,
                                qAddress.telephone,
                                qAddress.userId
                        )
                ).from(qAddress)
                .where(builder).offset(pageNum * pageSize).limit(pageSize).fetchResults();
    }

    @Transactional(rollbackFor = {Exception.class})
    public Result saveAddress(Long id,String name,String telephone,Long provinceId,Long cityId,Long areaId,
                              String detail,Integer isDefault,String province,String city,String area) {
        Long userId = this.userSessionManager.getUserId();
        if (1 == isDefault) {
            List<Address> addressList = this.addressRepository.findByUserId(userId);
            for (Address address1 : addressList) {
                address1.setIsDefault(Integer.valueOf(0));
                this.addressRepository.saveAndFlush(address1);
            }
        }
        Address address = null;
        if (id != null) {
            address = this.addressRepository.findById(id).get();
            address.setUserId(userId);
            address.setName(name);
            address.setProvince(province);
            address.setProvinceId(provinceId);
            address.setCity(city);
            address.setCityId(cityId);
            address.setArea(area);
            address.setAreaId(areaId);
            address.setDetail(detail);
            address.setIsDefault(isDefault);
            address.setTelephone(telephone);
            this.addressRepository.saveAndFlush(address);
        } else {
            address = new Address();
            address.setUserId(userId);
            address.setId(Snowflake.generateId());
            address.setName(name);
            address.setProvince(province);
            address.setProvinceId(provinceId);
            address.setCity(city);
            address.setCityId(cityId);
            address.setArea(area);
            address.setAreaId(areaId);
            address.setDetail(detail);
            address.setIsDefault(isDefault);
            address.setTelephone(telephone);
            this.addressRepository.save(address);
        }
        return Result.ok();
    }

    @Transactional(rollbackFor = {Exception.class})
    public Result saveDefaultAddress(Long addressId,Integer isdefault) {
        List<Address> addressList = this.addressRepository.findByUserId(this.userSessionManager.getUserId());
        for (Address address : addressList) {
            if (address.getId().compareTo(addressId) == 0) {
                if (1 == isdefault) {
                    address.setIsDefault(Integer.valueOf(1));
                } else {
                    address.setIsDefault(Integer.valueOf(0));
                }
            } else {
                address.setIsDefault(Integer.valueOf(0));
            }
            this.addressRepository.saveAndFlush(address);
        }
        return Result.ok();
    }

    public Result<Address> findDefaultAddress(Long userId) {
        Address address = this.addressRepository.findByUserIdOrderByIsDefaultDesc((userId != null) ? userId : this.userSessionManager.getUserId());
        return Result.ok(address);
    }

    public Result detailAddress(Long addressId) {
        return Result.ok(this.addressRepository.findById(addressId));
    }

    public Result delete(Long addressId) {
        addressRepository.deleteById(addressId);
        return Result.ok();
    }
}
